
public class PieChart
{
  private int x;
  private int y;
  private int w;
  private int h;
  private int diameter;
  private color [] pieColor;
  private color [] colorBlind;
  private int num;
  private float [] angs;
  private color legendColor;
  boolean showLegend;
  private int [] value;
  private int space;  //space between chart and legend

  int pieCount ;
  boolean isTotal ;
  private boolean [] genreFlag;
  private int maxPieNum;
  private boolean isColorBlind;


  PieChart(int xp, int yp, int wid, int hei,int dia)
  {
    space = 5;
    this.x = xp;
    this.y = yp;
    this.w = wid;
    this.h = hei;
    this.diameter = dia-space;
    num= genreName.length;
    value = new int [genreName.length];
    setupColor();
    angs = new float[num];
    showLegend = true;
    initializeAngs();
    pieCount = 0;
    isTotal = true;
    genreFlag = new boolean[genreName.length];
    maxPieNum = 5;    
    isColorBlind = false;
  }

  PieChart( int n,int xp, int yp, int wid, int hei,int dia)
  {
    space = 5;
    this.x = xp;
    this.y = yp;
    this.w = wid;
    this.h = hei;
    this.diameter = dia-space;
    this.num = n;

    value = new int[genreName.length];
    setupColor();
    angs = new float [genreName.length];
    initializeAngs();
    showLegend = false;
    pieCount = 0;
    isTotal = false;
    genreFlag = new boolean[genreName.length];
    maxPieNum=n;
    isColorBlind =false;
  }

  private void intializeFlag()
  {
    for(int i =0;i<genreName.length;i++)
    {
      genreFlag[i]=false;
    }
  }

  private void initializeAngs()
  {
    //initial values
    for(int i =0;i<genreName.length;i++)
    {
      value[i]=0;
    }
    for(int i =0;i<genreName.length;i++)
    {
      angs[i]=-1;
    }
  }

  private void setupColor()
  {
    pieColor =  new color [genreName.length];   
    legendColor=color(255,255,255);
    pieColor[0]=color(#F90606);
    pieColor[1]=color(#D5057E) ;
    pieColor[2]=color(#8705C8) ;
    pieColor[3]=color(#2505C8) ;
    pieColor[4]=color(#0556C8) ;
    pieColor[5]=color(#0598C8) ;
    pieColor[6]=color(#05C805) ;
    pieColor[7]=color(#AAE105) ;
    pieColor[8]=color(#F9F906) ;
    pieColor[9]=color(#F9C806) ;
    pieColor[10]=color(#F99806) ;
    pieColor[11]=color(#F96706) ;
    pieColor[12]=color(#FBC16A) ;
    pieColor[13]=color(#FBFB6A) ;
    pieColor[14]=color(#5EDE5E) ;
    pieColor[15]=color(#5E93DE) ;
    pieColor[16]=color(#B35EDE) ;
    pieColor[17]=color(#FB6A6A);

    //set colors to support color blindness
    colorBlind = new color [genreName.length];

    colorBlind[0]=color(#908121);
    colorBlind[1]=color(#5870B5);
    colorBlind[2]=color(#0056B6) ;
    colorBlind[3]=color(#003D80) ;
    colorBlind[4]=color(#0059BD) ;
    colorBlind[5]=color(#7E8CC1) ;
    colorBlind[6]=color(#C5AF00) ;
    colorBlind[7]=color(#EED300) ;
    colorBlind[8]=color(#FFF7D8) ;
    colorBlind[9]=color(#EDD30B) ;
    colorBlind[10]=color(#C8B213) ;
    colorBlind[11]=color(#AA9719) ;
    colorBlind[12]=color(#E0CB6E);
    colorBlind[13]=color(#A2997F) ;
    colorBlind[14]=color(#397FFF) ;
    colorBlind[15]=color(#A9AFD4) ;
    colorBlind[16]=color(#F7DE60) ;
    colorBlind[17] =color(#FFF4CB);

   
  }
  public void changeColorMode()
  {
    isColorBlind = !isColorBlind;
    //println("Now isColorBlind is "+ isColorBlind);
  }

  public void addGenre(int n)
  {
    if(isTotal) //Total pie graph pass this function
      return;
    if( n ==18) // For all genres
      return;
    if( genreFlag[n]!=true) //If the Nth isn`t included in current piechart
    {
      if( pieCount<maxPieNum)//If there is enough room
      {
        genreFlag[n]=true;
        pieCount ++;
      }
    }
  }
  public void removeGenre( int n)
  {
    if(isTotal) //Total pie graph pass this function
      return;
    if( n ==18) // For all genres
      return;
    if(pieCount ==0) //If no pie exists
      return;
    if( genreFlag[n] ==true) //If the Nth is included in current piechart
    {
      genreFlag[n]=false;
      pieCount--;
    }
  }
  public void clear()
  {
    if(isTotal) //Total pie graph pass this function
      return;
    for( int i = 0 ;i<genreName.length;i++)
    {
      genreFlag[i]=false;
    }
    pieCount = 0 ;
  }



  // Every income value array should be a int array with 18 elements;
  // That is, len = 18;
  public void setupValue( )
  {
    initializeAngs();
  }

  public void draw()
  {

    //Draw the frame
    noFill();
    strokeWeight(1);
    stroke(175, 50);
    //rectMode(CORNERS);
    //rect(x, y, w, h);


    float dateMin = filmTimeLine.getYearMin();
    float dateMax = filmTimeLine.getYearMax();
    int yearMin = int(dateMin);
    int yearMax = int(dateMax);
    float total = 0;
    int sum = (num<genreName.length?num:genreName.length);
    for (int i = 0; i < genreName.length; i++)
    {
      value[i]=0;
    }
    for (int yr = yearMin; yr <= yearMax; yr++) { 
      for (int m = 1; m < 12; m++) {
        for (int i = 0; i < genreName.length; i++)
        {
          if( isTotal)
          {
            value[i]+= dataArray[i].getCount(yr,m);
            total += dataArray[i].getCount(yr, m);
          }
          else
          {
            if(genreFlag[i])
            {
              value[i]+= dataArray[i].getCount(yr,m);
              total += dataArray[i].getCount(yr, m);
            }
          }
        }
      }
    }
    for( int j =0;j<genreName.length;j++)
    {
      angs[j] = 360*(value[j]/total);
    }

  if(showLegend)
  {
    fill(255);
    textSize(12);    
    textAlign(LEFT, TOP);
    rectMode(CORNER);
    text("Percentages: Press B to see safe color",x+20,y,diameter*3,20);
  }

    float lastAng = 0 ;
    //println("angs.length is "+angs.length);

    for(int i = 0;i<genreName.length;i++)
    {
      if( angs[i]!= -1)
      {
        fill(getColor(i));

        arc(x+diameter/2+space*2,y+space*4+diameter/2,diameter,diameter,lastAng,lastAng+radians(angs[i]));
        lastAng+=radians(angs[i]);
      }
    }    
    if( showLegend)
      drawLegend();
  }
  private void drawLegend()
  {
    //Draw inner frame
    strokeWeight(1);
    noFill();
    stroke(175, 50);
    rectMode(CORNER);
    rect(x+space,x+w-space*2, y, h+30-space);  

    int xp=  x+diameter+space*2;
    int yp = y+space*4;
    int legendWidth = 12;
    int legendHeight =12;
    //space between legend and text
    int space = 10; 
    float increY = 17;
    for(  int i =0;i<pieColor.length;i++)
    {
      stroke(255);
      strokeWeight(0.5);
      fill( getColor(i));
      //println("X is "+x+", y is "+ y+", width is"+legendWidth+", height is"+legendHeight);
      rectMode(CORNER);
      rect(xp+space,yp,legendWidth,legendHeight);
      textSize(12);   
      textAlign(LEFT,TOP);
      fill(legendColor);
      if( i ==5)      
        text( "Document",xp+legendWidth+space*2,yp);
      else
        text( genreName[i],xp+legendWidth+space*2,yp);
      yp += increY;
    }
  }
  public void showLegend(boolean show)
  {
    showLegend = show;
  }

  public color getColor(int index) {
    if (index >= pieColor.length || index < 0)
    {
      return #F0E1E1;
    }
    else
    {

      if(!isColorBlind)
      {
        return pieColor[index];
      }
      else
      {
        return colorBlind[index];
      }
    }
  }
}

